﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using PloobsEngine.Modelo;
using PloobsEngine.SceneControl;
using PloobsEngine.Cameras;
using PloobsEngine.Modelo.Animation;
using PloobsEngine.Light;
using XNAnimation.Effects;

namespace PloobsEngine.Material
{
    public class CustomAnimationShader : IShader
    {
        /// <summary>
        /// Serialization
        /// </summary>
        public CustomAnimationShader()
        {
        }

        public CustomAnimationShader(IAnimatedController ac , bool useBump, bool useSpecular, bool useGlow)
        {
            this.ac = ac;
            this.useBump = useBump;
            this.useSpecular = useSpecular;
            this.useGlow = useGlow;
            Initialize();
        }

        public CustomAnimationShader(IAnimatedController ac, bool useBump, bool useSpecular, bool useGlow, IObject obj, IAnimatedController Followed,String boneName)
        {
            this.ac = ac;
            this.useBump = useBump;
            this.useSpecular = useSpecular;
            this.useGlow = useGlow;
            this.Followed = Followed;
            followBone = true;
            this.boneName = boneName;
            this.Followobj = obj;
            Initialize();
        }

        IObject Followobj;
        String boneName;
        IAnimatedController Followed;
        bool followBone = false;
        private bool useGlow;        
        private bool useBump;
        private bool useSpecular;

        private IAnimatedController ac;
        private Matrix WorldMatrix;

        public override MaterialType MaterialType
        {
            get { return MaterialType.DEFERRED; }
        }    

        public override void Update(IObject ent, IList<PloobsEngine.Light.ILight> lights)
        {
            this.WorldMatrix = ent.getWorldMatrix();         
        }

        public override void Draw(IModelo mod, IRenderHelper render, ICamera cam)
        {
            AnimatedModel modelo = mod as AnimatedModel;
            foreach (ModelMesh modelMesh in modelo.getModelMeshes())
            {
                foreach (ModelMeshPart meshPart in modelMesh.MeshParts)
                {
                    SkinnedModelBasicEffect basicEffect = (SkinnedModelBasicEffect)meshPart.Effect;                    
                    basicEffect.CurrentTechnique = basicEffect.Techniques["DEFERREDCUSTOM"];                   

                    basicEffect.Parameters["diffuseMap0"].SetValue(modelo.getTexture(TextureType.DIFFUSE));
                    basicEffect.Parameters["diffuseMapEnabled"].SetValue(true);
                    basicEffect.Parameters["normalMapEnabled"].SetValue(useBump);
                    basicEffect.Parameters["glowMapEnabled"].SetValue(useGlow);
                    basicEffect.Parameters["specularMapEnabled"].SetValue(useSpecular);

                    if (useGlow)
                    {                        
                        basicEffect.Parameters["glowMap0"].SetValue(modelo.getTexture(TextureType.GLOW));
                    }
                    if (useBump)
                    {                        
                        basicEffect.Parameters["normalMap0"].SetValue(modelo.getTexture(TextureType.BUMP));
                    }
                    if (useSpecular)
                    {
                        basicEffect.Parameters["specularMap0"].SetValue(modelo.getTexture(TextureType.SPECULAR));
                    }

                    if (followBone)
                    {
                        basicEffect.World = Followed.GetBoneAbsoluteTransform(boneName) * Followobj.getWorldMatrix();
                        basicEffect.Bones = modelo.getBonesTransformation() ;
                    }
                    else
                    {
                        basicEffect.World = WorldMatrix;
                        basicEffect.Bones = ac.GetBoneTransformations();
                    }                    
                    
                    basicEffect.View = cam.View;
                    basicEffect.Projection = cam.Projection;
                }


                modelMesh.Draw();
            }




        }
    }
}
